#ifndef BITFLAGS_H
#define BITFLAGS_H
#pragma once


#pragma warning( disable : 4800 )


#define FLAG(x) (1<<(x))
#define TEST_BIT(flag, bit) (((flag.value) & FLAG((bit))) !=0)
#define TEST_ALL(flag, set) (((flag.value) & (set)) == (set))
#define TEST_ANY(flag, set) (((flag.value) & (set)) !=0)
#define SET_BIT(flag, bit) ((flag.value) |= FLAG((bit)))
#define CLEAR_BIT(flag, bit) ((flag.value) &= ~FLAG((bit)))
#define SET_ALL(flag, set) ((flag.value) |= (set))
#define CLEAR_ALL(flag, set) ((flag.value) &= ~(set))


template <class T>
class TwBitFlags
{
public:

	T value;

	 
	TwBitFlags();
	TwBitFlags(T data);
	TwBitFlags(const TwBitFlags& Src);
	~TwBitFlags();

	 
	TwBitFlags& operator=( const TwBitFlags& Src);
	TwBitFlags& operator=( T Src);
	operator T()const {return(value);};
	bool operator==(const TwBitFlags& Src)const;
	bool operator!=(const TwBitFlags& Src)const;

	 
	void set(T settings);
	void clear();
	void setFlags(T settings);
	void clearFlags(T settings);
	void setBit(int bit);
	void clearBit(int bit);
	void setBit(int bit, bool setting);

	 
	bool isEmpty()const;
	bool testBit(int bit)const;
	bool testFlags(T test)const;
	bool testAny(T test)const;

	int	totalBits()const;
	int	totalSet()const;
};

 
typedef TwBitFlags<UINT8> u8Flags;	 
typedef TwBitFlags<UINT16> u16Flags;  
typedef TwBitFlags<UINT32> u32Flags;  

 
template <class T>
inline TwBitFlags<T>::TwBitFlags()
:value(0)
{
}

template <class T>
inline TwBitFlags<T>::TwBitFlags(T settings)
:value(settings)
{
}

template <class T>
inline TwBitFlags<T>::TwBitFlags( const TwBitFlags& Src)
:value(Src.value)
{
}

 
template <class T>
inline TwBitFlags<T>::~TwBitFlags()
{
}

 
template <class T>
inline TwBitFlags<T>& TwBitFlags<T>::operator=( const TwBitFlags<T>& Src)
{
	value = Src.value;
	return(*this);
}

template <class T>
inline TwBitFlags<T>& TwBitFlags<T>::operator=( T Src)
{
	value = Src;
	return(*this);
}

template <class T>
bool TwBitFlags<T>::operator==( const TwBitFlags& Src)const
{
	return(value == Src.value);
}

template <class T>
bool TwBitFlags<T>::operator!=( const TwBitFlags& Src)const
{
	return(value != Src.value);
}

 
template <class T>
inline void TwBitFlags<T>::set(T settings)
{
	value = settings;
}

template <class T>
inline void TwBitFlags<T>::clear()
{
	value = 0;
}

template <class T>
inline void TwBitFlags<T>::setFlags(T settings)
{
	value |= settings;
}

template <class T>
inline void TwBitFlags<T>::clearFlags(T settings)
{
	value &= ~settings;
}


template <class T>
inline void TwBitFlags<T>::setBit(int bit)
{
	value |= (1<<bit);
}

template <class T>
inline void TwBitFlags<T>::setBit(int bit, bool setting)
{
	if (setting)
	{
		value |= (1<<bit);
	}
	else
	{
		clearBit(bit);
	}
}

template <class T>
inline void TwBitFlags<T>::clearBit(int bit)
{
	value &= (~(1<<bit));
}

 
template <class T>
inline bool TwBitFlags<T>::isEmpty()const
{
	return(value == static_cast<T>(0));
}

template <class T>
inline bool TwBitFlags<T>::testBit(int bit)const
{
	return(value & (1<<bit));
}


template <class T>
inline bool TwBitFlags<T>::testFlags(T test)const
{
	return((value & test) == test);
}

template <class T>
inline bool TwBitFlags<T>::testAny(T test)const
{
	return(value & test);
}

template <class T>
inline int TwBitFlags<T>::totalBits()const
{
	return(sizeof(T)<<3);
}

template <class T>
inline int TwBitFlags<T>::totalSet()const
{
	int count=0;
	int total = totalBits();
	T TestValue = value;
	
	for (int i=total;i;--i)
	{
		count += (TestValue & 1);
		TestValue >>= 1;
	}
	return(count);
}

 


#pragma warning( default : 4800 )

#endif  

 